package org.example.dom4j;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import org.example.translation.*;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 翻译
 */
public class Dom4j {

    public static void main(String[] args) {
        Dom4j dom4j = new Dom4j();
        //翻译单个文字
//        TranslationPostBean translationPostBean = new TranslationPostBean();
//        translationPostBean.setSourceString("你好 世界");
//        translationPostBean.setSourceCountry("zh");
//        translationPostBean.setTargetCountry("en");
//        dom4j.translation(translationPostBean);

        //翻译一一整个文件夹内所有的value下的strings文件
        //dom4j.translationEntireValueFolder("C:\\Users\\abbas\\Desktop\\LangTest", new DefaultCountryTransformer(), new FilledTranslationConsumer());

        //将某个文件翻译为另一个语言
        //dom4j.translationXXtoXX(new DefaultCountryTransformer(),"C:\\Users\\abbas\\Desktop\\LangTest\\values","zh","",new AllReplaceTranslationConsumer());

        //把部分string找出来汇集成一个表
        //dom4j.findWithKey("C:\\Users\\abbas\\Desktop\\LangTest", Arrays.asList("sport_type_offline", "sport_type_All", "sport_history_steps_name", "sport_history_time_name"));
    }


    private static final ExecutorService ioThread = Executors.newCachedThreadPool();

    /**
     * 翻译单段文字
     * @param translationPostBean 需要翻译的数据
     */
    private void translation(TranslationPostBean translationPostBean){
        TranslationManager instance = TranslationManager.getInstance();
        TranslationResponseBean translation = instance.translation(translationPostBean);
        System.out.println(translation);
    }

    /**
     * 全量翻译（但不准确，取决于 translationType 参数
     * 逻辑是：给一个安卓res文件夹，程序获取文件夹下所有“values-xx”文件夹，解析“values-xx”文件夹下所有string.xml。执行翻译逻辑
     *
     * @param valueFolderPath    安卓res文件夹
     * @param countryTransformer 源语言国家简写。如英语为“en”。翻译时是根据“values-xx”文件夹命名的国家简写识别的。
     * @param translationType    执行翻译的实际类。不同实现执行的逻辑不一样
     */
    public void translationEntireValueFolder(String valueFolderPath, StringFolderCountryTransformer countryTransformer, AbsTranslationConsumer translationType) {
        System.out.println("程序开始");
        //桌面待翻译文件
        File file = new File(valueFolderPath);
        File[] files = file.listFiles();
        System.out.println("已获取到目标文件");

        //文件夹里面的文件提取出来
        if (files == null || files.length == 0) return;

        //按翻译文件的国家代码分个类
        Map<String, File> countryMap = new HashMap<>();
        Arrays.stream(files)
                .forEach(f -> {
                    String country = countryTransformer.apply(f.getName());
                    countryMap.put(country, f);
                });
        System.out.println("文件已分类");

        //找需要翻译的文件
        Optional<File> sourceFile = Optional.ofNullable(countryMap.getOrDefault(countryTransformer.getSourceCountry(), null));

        //没有找到直接睡觉
        if (!sourceFile.isPresent()) {
            throw new RuntimeException("没有找到源语言文件");
        }
        System.out.println("已找到翻译源文件");

        //万事俱备
        System.out.println("抽取源文件KV值");
        File noNullSourceFile = sourceFile.get();
        File savedFilePath = new File("..\\values");
        if (savedFilePath.exists()) savedFilePath.delete();
        savedFilePath.mkdir();


        StringsXMLData sourceXMLData = Dom4jDocUtil.convertDocumentToData(noNullSourceFile.getAbsolutePath(), countryTransformer);
        if (sourceXMLData == null) {
            System.out.println(noNullSourceFile + "/string.xml 文件未找到！");
            return;
        }

        System.out.println("源文件KV值抽取完毕");

        //把不需要翻译的源文件从翻译列表当中删除
        countryMap.remove(countryTransformer.getSourceCountry());

        System.out.println("开始翻译");
        //开始翻译 遍历需要翻译的文件
        for (String next : countryMap.keySet()) {
            File waitingTranslationFile = countryMap.get(next);
            System.out.println("开始翻译：" + waitingTranslationFile.getName() + " 文件");

            System.out.println("抽取需要翻译的文件KV");
            //解析文件
            StringsXMLData translationXMLData = Dom4jDocUtil.convertDocumentToData(waitingTranslationFile.getAbsolutePath(), countryTransformer);
            if (translationXMLData == null) {
                //new RuntimeException(waitingTranslationFile + "/string.xml 文件未找到！").printStackTrace();
                System.out.println(waitingTranslationFile + "/string.xml 文件未找到！");
                continue;
            }
            System.out.println("抽取完成");
            translationType.accept(sourceXMLData, translationXMLData);
            saveDocument(waitingTranslationFile.getName(), translationXMLData.getSourceDocument());
        }
    }

    /**
     * 翻译单个语言文件
     *
     * @param stringsXmlPath 源国家语言文件位置
     * @param targetCountry  目标语言简写
     * @param savedFilePath  目标翻译文件位置
     * @param consumer       翻译者
     */
    private void translationXXtoXX(StringFolderCountryTransformer countryTransformer, String stringsXmlPath, String targetCountry, String savedFilePath, TranslationConsumer consumer) {
        //把原文件数据提取出来
        StringsXMLData stringsXmlFileData = Dom4jDocUtil.convertDocumentToData(stringsXmlPath, countryTransformer);
        //新建一个文件存翻译数据
        StringsXMLData newDocument = Dom4jDocUtil.createAndroidStringXmlDocument();
        //给新文件设置好对应的语言类型，这很重要
        newDocument.setCountry(targetCountry);
        //开始翻译
        consumer.accept(stringsXmlFileData, newDocument);
        //保存数据
        saveDocument(savedFilePath, newDocument.getSourceDocument());
    }

    /**
     * 文件保存
     *
     * @param saveFilePath 保存路径
     * @param document     dom4j类
     */
    private void saveDocument(String saveFilePath, Document document) {
        ioThread.submit(() -> {
            try {
                new File(System.getProperty("user.dir") + "\\values\\").mkdir();
                new File(System.getProperty("user.dir") + "\\values\\" + saveFilePath).mkdir();
                File saveFile = new File(System.getProperty("user.dir") + "\\values\\" + saveFilePath + "\\strings.xml");
                System.out.println("文件写入：" + saveFile.getAbsolutePath());
                XMLWriter writer = new XMLWriter(new FileWriter(saveFile));
                writer.write(document);
                writer.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
    }

    /**
     * 从文件夹当中所有的语言文件抽取出目标key的条目并将其生成为单个表格
     *
     * @param valueFolderPath 安卓res文件
     * @param keys            需要抽取的key
     * @throws IOException    e
     * @throws WriteException e
     */
    private void findWithKey(String valueFolderPath, List<String> keys) {
        System.out.println("程序开始");
        //桌面待翻译文件
        File file = new File(valueFolderPath);
        File[] files = file.listFiles();
        System.out.println("已获取到目标文件");

        //文件夹里面的文件提取出来
        if (files == null || files.length == 0) return;

        //按翻译文件的国家代码分个类
        Map<String, File> countryMap = new HashMap<>();
        DefaultCountryTransformer defaultCountryTransformer = new DefaultCountryTransformer();
        Arrays.stream(files)
                .forEach(f -> countryMap.put(defaultCountryTransformer.apply(f.getName()), f));
        System.out.println("文件已分类");

        ArrayList<String> country = new ArrayList<>();
        List<StringsXMLData> xmlData = new ArrayList<>();
        ArrayList<ArrayList<String>> data = new ArrayList<>();
        Iterator<String> iterator = countryMap.keySet().iterator();
        while (iterator.hasNext()) {
            String c = iterator.next();
            File f = countryMap.get(c);
            country.add(Constants.AbbreviationsComparisonTable.getOrDefault(c, c));
            xmlData.add(Dom4jDocUtil.convertDocumentToData(f.getPath()));
        }
        for (String key : keys) {
            ArrayList<String> strings = new ArrayList<>();
            for (StringsXMLData xmlDatum : xmlData) {
                Element element = xmlDatum.getSourceKV().get(key);
                strings.add(element.getText());
            }
            data.add(strings);
        }

        try {
            WritableWorkbook workbook = Workbook.createWorkbook(new File("output.xls"));
            WritableSheet page = workbook.createSheet("page", 0);
            for (int i = 0; i < country.size(); i++) {
                page.addCell(new Label(i, 0, country.get(i)));
            }
            for (int i = 0; i < data.size(); i++) {
                ArrayList<String> strings = data.get(i);
                for (int i1 = 0; i1 < strings.size(); i1++) {
                    page.addCell(new Label(i1, i + 1, strings.get(i1)));
                }
            }
            workbook.write();
            workbook.close();
        } catch (IOException | WriteException e) {
            throw new RuntimeException(e);
        }
    }

}
